{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cf9e8dc6",
   "metadata": {},
   "source": [
    "yield (子)生成器——适用于简单的生成操作；\n",
    "\n",
    "yield from  委托生成器——在处理复杂的生成器链，委派任务和异常更加高效\n",
    "\n",
    "\n",
    "yield from 后面需要*加可迭代对象*，可以是普通的可迭代对象，也可以是迭代器或者生成器\n",
    "\n",
    "yield from 相当于 yield 嵌套一个for循环"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5e202d66",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "count pre: 0\n",
      "------1\n",
      "count after: 1\n",
      "count pre: 1\n",
      "10.0\n",
      "------2\n",
      "count after: 2\n",
      "count pre: 2\n",
      "15.0\n",
      "------3\n",
      "count after: 3\n",
      "count pre: 3\n",
      "20.0\n"
     ]
    }
   ],
   "source": [
    "#子生成器\n",
    "def average_gen():\n",
    "    total = 0\n",
    "    count = 0\n",
    "    average = 0\n",
    "    while True:\n",
    "        print('count pre:', count)\n",
    "        new_num = yield average     # 生成器\n",
    "        count += 1\n",
    "        print('count after:', count)\n",
    "        total += new_num\n",
    "        average = total/count\n",
    "\n",
    "#委托生成器\n",
    "def proxy_gen():\n",
    "    while True:\n",
    "        yield from average_gen()  # yield from 后加了 生成器\n",
    "\n",
    "#调用方\n",
    "\n",
    "def main():\n",
    "    calc_average = proxy_gen()\n",
    "    next(calc_average)  # 预激生成器，到yeild前停止\n",
    "    print('------1')\n",
    "    print(calc_average.send(10)) # 打印 10.0  生成器对象 .send() 方法，用于传参\n",
    "    print('------2')\n",
    "    print(calc_average.send(20)) # 打印 15.0\n",
    "    print('------3')\n",
    "    print(calc_average.send(30)) # 打印：20.0\n",
    "\n",
    "main()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "fb302d23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "----\n",
      "2\n",
      "----\n",
      "3\n",
      "----\n",
      "33\n",
      "----\n",
      "生成器已经完成\n"
     ]
    }
   ],
   "source": [
    "def simple_generator(): # 简单生成器\n",
    "    yield 1\n",
    "    yield 2\n",
    "    yield 3\n",
    "\n",
    "simple_generator()\n",
    "\n",
    "\n",
    "\n",
    "def sub_generator():  # 子生成器\n",
    "    yield 1\n",
    "    yield 2\n",
    "    yield 3\n",
    "\n",
    "def delegating_generator():  # 委托生成器\n",
    "    yield from sub_generator()   # yield from 后加子生成器\n",
    "    yield 33\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    #main()\n",
    "    gen = delegating_generator()\n",
    "    try:\n",
    "        while True:\n",
    "            print(next(gen))\n",
    "            print('----')\n",
    "    except StopIteration:\n",
    "        print('生成器已经完成')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c9320f02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['A', 'B', 'C', 1, 2, 3, 'name', 'age', 3, 4]\n",
      "['A', 'B', 'C', 1, 2, 3, 'name', 'age']\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# yield from 相当于 yield嵌套一个for循环\n",
    "\n",
    "astr = 'ABC'      # 字符串\n",
    "alist = [1,2,3]   # 列表\n",
    "adict = {'name':'lhh', 'age':18}  # 字典\n",
    "agen = (i for i in range(3,5))    # 迭代器\n",
    "\n",
    "def gen(*args, **kw):\n",
    "    for item in args:\n",
    "        for i in item:  # 这里是对yield的for循环嵌套访问，应该可以用next()代替\n",
    "            yield i  # 子生成器\n",
    "\n",
    "new_list = gen(astr, alist, adict, agen)\n",
    "print(list(new_list))\n",
    "\n",
    "def gen2(*args, **kw):\n",
    "    for item in args:\n",
    "        yield from item  # yield from 后加上可迭代对象\n",
    "\n",
    "new_list2 = gen2(astr, alist, adict, agen)\n",
    "print(list(new_list2)) # new_list2 转换成 ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 3, 4]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "2cba4615",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1111----\n",
      "start: a= 14\n",
      "2222----\n",
      "received: b= 28\n",
      "3333----\n",
      "received: c= 90\n",
      "90\n"
     ]
    }
   ],
   "source": [
    "# yield可以通过 子生成器.send() 方法传参；\n",
    "# 传参是按yeild 的顺序的；\n",
    "\n",
    "def simple_coro2(a):\n",
    "    print('start: a=', a)\n",
    "    b = yield a\n",
    "    print('received: b=', b)\n",
    "    c = yield b+a\n",
    "    print('received: c=', c)\n",
    "    return c\n",
    "\n",
    "my_coro2 = simple_coro2(14)\n",
    "print('1111----')\n",
    "next(my_coro2)\n",
    "print('2222----')\n",
    "my_coro2.send(28)\n",
    "print('3333----')\n",
    "try:\n",
    "    my_coro2.send(90)\n",
    "except StopIteration as e:\n",
    "    print(e.value)\n",
    "    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "513aefa5",
   "metadata": {},
   "source": [
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fce3da1e",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "schedule",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
